/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2002-2006 * Sleepycat Software. All rights reserved. * * $Id: FileSummary.java,v 1.1 2006/05/06 09:01:57 ckaestne Exp $ */ package com.sleepycat.je.cleaner; import java.nio.ByteBuffer; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.log.LogReadable; import com.sleepycat.je.log.LogUtils; import com.sleepycat.je.log.LogWritable; public class FileSummary implements LogWritable, LogReadable { /* Persistent fields. */ public int totalCount; // Total # of log entries public int totalSize; // Total bytes in log file public int totalINCount; // Number of IN log entries public int totalINSize; // Byte size of IN log entries public int totalLNCount; // Number of LN log entries public int totalLNSize; // Byte size of LN log entries public int obsoleteINCount; // Number of obsolete IN log entries public int obsoleteLNCount; // Number of obsolete LN log entries /** * Creates an empty summary. */ public FileSummary() { } /** * Returns whether this summary contains any non-zero totals. */ public boolean isEmpty() { return totalCount == 0 && totalSize == 0 && obsoleteINCount == 0 && obsoleteLNCount == 0; } /** * Returns the approximate byte size of all obsolete LN entries. */ public int getObsoleteLNSize() { if (totalLNCount == 0) { return 0; } /* Use long arithmetic. */ long totalSize = totalLNSize; /* Scale by 255 to reduce integer truncation error. */ totalSize <<= 8; long avgSizePerLN = totalSize / totalLNCount; return (int) ((obsoleteLNCount * avgSizePerLN) >> 8); } /** * Returns the approximate byte size of all obsolete IN entries. */ public int getObsoleteINSize() { if (totalINCount == 0) { return 0; } /* Use long arithmetic. */ long totalSize = totalINSize; /* Scale by 255 to reduce integer truncation error. */ totalSize <<= 8; long avgSizePerIN = totalSize / totalINCount; return (int) ((obsoleteINCount * avgSizePerIN) >> 8); } /** * Returns an estimate of the total bytes that are obsolete. */ public int getObsoleteSize() throws DatabaseException { if (totalSize > 0) { /* Leftover (non-IN non-LN) space is considered obsolete. */ int leftoverSize = totalSize - (totalINSize + totalLNSize); int obsoleteSize = getObsoleteLNSize() + getObsoleteINSize() + leftoverSize; /* * Don't report more obsolete bytes than the total. We may * calculate more than the total because of (intentional) * double-counting during recovery. */ if (obsoleteSize > totalSize) { obsoleteSize = totalSize; } return obsoleteSize; } else { return 0; } } /** * Returns the total number of entries counted. This value is guaranted * to increase whenever the tracking information about a file changes. It * is used a key discriminator for FileSummaryLN records. */ public int getEntriesCounted() { return totalCount + obsoleteLNCount + obsoleteINCount; } /** * Returns the number of non-obsolete LN and IN entries. */ public int getNonObsoleteCount() { return totalLNCount + totalINCount - obsoleteLNCount - obsoleteINCount; } /** * Reset all totals to zero. */ public void reset() { totalCount = 0; totalSize = 0; totalINCount = 0; totalINSize = 0; totalLNCount = 0; totalLNSize = 0; obsoleteINCount = 0; obsoleteLNCount = 0; } /** * Add the totals of the given summary object to the totals of this object. */ public void add(FileSummary o) { totalCount += o.totalCount; totalSize += o.totalSize; totalINCount += o.totalINCount; totalINSize += o.totalINSize; totalLNCount += o.totalLNCount; totalLNSize += o.totalLNSize; obsoleteINCount += o.obsoleteINCount; obsoleteLNCount += o.obsoleteLNCount; } /** * @see LogWritable#getLogSize */ public int getLogSize() { return 8 * LogUtils.getIntLogSize(); } /** * @see LogWritable#writeToLog */ public void writeToLog(ByteBuffer buf) { LogUtils.writeInt(buf, totalCount); LogUtils.writeInt(buf, totalSize); LogUtils.writeInt(buf, totalINCount); LogUtils.writeInt(buf, totalINSize); LogUtils.writeInt(buf, totalLNCount); LogUtils.writeInt(buf, totalLNSize); LogUtils.writeInt(buf, obsoleteINCount); LogUtils.writeInt(buf, obsoleteLNCount); } /** * @see LogReadable#readFromLog */ public void readFromLog(ByteBuffer buf, byte entryTypeVersion) { totalCount = LogUtils.readInt(buf); totalSize = LogUtils.readInt(buf); totalINCount = LogUtils.readInt(buf); totalINSize = LogUtils.readInt(buf); totalLNCount = LogUtils.readInt(buf); totalLNSize = LogUtils.readInt(buf); obsoleteINCount = LogUtils.readInt(buf); if (obsoleteINCount == -1) { /* * If INs were not counted in an older log file written by 1.5.3 or * earlier, consider all INs to be obsolete. This causes the file * to be cleaned, and then IN counting will be accurate. */ obsoleteINCount = totalINCount; } obsoleteLNCount = LogUtils.readInt(buf); } /** * @see LogReadable#dumpLog */ public void dumpLog(StringBuffer buf, boolean verbose) { buf.append("<summary totalCount=\""); buf.append(totalCount); buf.append("\" totalSize=\""); buf.append(totalSize); buf.append("\" totalINCount=\""); buf.append(totalINCount); buf.append("\" totalINSize=\""); buf.append(totalINSize); buf.append("\" totalLNCount=\""); buf.append(totalLNCount); buf.append("\" totalLNSize=\""); buf.append(totalLNSize); buf.append("\" obsoleteINCount=\""); buf.append(obsoleteINCount); buf.append("\" obsoleteLNCount=\""); buf.append(obsoleteLNCount); buf.append("\"/>"); } /** * Never called. * @see LogReadable#getTransactionId */ public long getTransactionId() { return -1; } /** * Never called. * @see LogReadable#logEntryIsTransactional */ public boolean logEntryIsTransactional() { return false; } public String toString() { StringBuffer buf = new StringBuffer(); dumpLog(buf, true); return buf.toString(); } }